<template>
    <div class="drag-form">
        <div class="drag-form-content">
            <div class="left">
                <h4 class="title">基础表单</h4>
                <vueDraggable
                    class="widget-draggable"
                    v-model="widgets"
                    v-bind="widgetsDragOptions"
                    :clone="widgetClone"
                    :move="widgetMove"
                    @end="widgetEnd"
                >
                    <el-col class="widget-col" :span="12" v-for="(item, index) in widgets" :key="index">
                        <div class="widget" @click="widgetClick(item)">
                            <FontIcon :icon="item.icon"></FontIcon>
                            {{item.label}}
                        </div>
                    </el-col>
                </vueDraggable>
            </div>
            <div class="center">
                <div class="center-toolbar">
                    <VoDragFormToolbar :schema="schema" :select-propery="selectProperty"></VoDragFormToolbar>
                </div>
                <div class="center-form">
                    <el-form :model="model" v-bind="schema.ui" :disabled="true">
                        <vueDraggable
                            class="form-draggable"
                            data-dragto="form"
                            v-model="schema.properties"
                            v-bind="formDragOptions"
                        >
                            <VoDragFormItem
                                v-for="(item, index) in schema.properties"
                                :property="item"
                                :col="schema.col"
                                :select-property="selectProperty"
                                :key="index"
                                @item-select="itemSelect"
                                @item-delete="itemDelete"
                                @item-copy="itemCopy"
                            >
                                <VoSchemaFormItem :model="model" :property="dragFormItem(item)" :col="schema.col">
                                </VoSchemaFormItem>
                            </VoDragFormItem>
                        </vueDraggable>
                        <div class="form-empty" v-if="!schema.properties || !schema.properties.length">从左侧拖拽或点击来添加字段</div>
                    </el-form>
                </div>
            </div>
            <div class="right">
                <VoDragFormPropertyEdit :widgets="schema.properties.map(e => e.model)" :schema="schema" :property="selectProperty"></VoDragFormPropertyEdit>
            </div>
        </div>
    </div>
</template>

<script>
import { baseDragSource, defaultSchema } from '../utils/drag'
import VueDraggable from 'vuedraggable'
import VoSchemaFormItem from '@/packages/SchemaForm/FormItem.vue'
import VoDragFormItem from './DragItem.vue'
import VoDragFormPropertyEdit from './PropertyEdit.vue'
import VoDragFormToolbar from './Toolbar.vue'
import { clone } from '@/utils/clone'

export default {
    name: 'VoDragForm',
    components: {
        VueDraggable,
        VoSchemaFormItem,
        VoDragFormItem,
        VoDragFormPropertyEdit,
        VoDragFormToolbar
    },
    data() {
        return {
            // widgets 数组
            widgets: baseDragSource,
            // widget 克隆对象
            widgetCloneData: null,
            // widgets 拖拽配置
            widgetsDragOptions: {
                sort: false,
                group: {
                    name: 'draggroup',
                    pull: 'clone',
                    put: false
                },
                handle: '.widget',
                chosenClass: 'widget-chosen',
                dataDragto: 'widgets'
            },
            // 当前选中表单
            selectProperty: null,
            // 表单 拖拽配置
            formDragOptions: {
                handle: '.drag-bar',
                chosenClass: 'form-chosen',
                animation: 200,
                group: 'draggroup',
                tag: 'el-row'
            },
            // 表单 绑定对象
            model: {},
            // 表单 schema
            schema: clone(defaultSchema)
        }
    },
    methods: {
        /**
         * 表单配置过滤
        */
        dragFormItem(item) {
            // el-select 开启多选的时候，由于必须绑定数组，所以切换的时候会报错。
            if (item.widget === 'select') {
                return {
                    ...item,
                    ui: {
                        ...item.ui,
                        multiple: false
                    },
                    rules: item.rules.filter(e => e._checked)
                }
            } else {
                return {
                    ...item,
                    rules: item.rules.filter(e => e._checked)
                }
            }
        },
        /**
         * 创建表单对象
        */
        createProperty(el) {
            const e = clone(el)
            return {
                model: `${e.widget}_${Math.floor(Math.random() * 1000000)}`,
                widget: e.widget,
                label: e.label,
                ...e.property
            }
        },
        /**
         * widget点击
        */
        widgetClick(e) {
            this.widgetCloneData = this.createProperty(e)
            this.schema.properties.push(this.widgetCloneData)
            this.selectProperty = this.widgetCloneData
        },
        /**
         * widget开始拖拽
        */
        widgetMove(e) {
            if (e.relatedContext.element && e.relatedContext.element.type === 'widget') return false;
            return true
        },
        /**
         * widget开始拖拽并克隆
        */
        widgetClone(e) {
            this.widgetCloneData = this.createProperty(e)
            return this.widgetCloneData
        },
        /**
         * widget拖拽结束
        */
        widgetEnd(e) {
            console.log('end');
            if (e.to.dataset.dragto === 'form') {
                this.selectProperty = this.widgetCloneData
            }
        },
        /**
         * 表单选中
        */
        itemSelect(p) {
            this.selectProperty = p
        },
        /**
         * 表单移除
        */
        itemDelete(p) {
            const index = this.schema.properties.findIndex(e => e === p);
            if (index !== -1) {
                if (
                    this.selectProperty &&
                    p.model === this.selectProperty.model
                ) {
                    this.selectProperty = null
                }
                this.schema.properties.splice(index, 1)
            }
        },
        /**
         * 表单复制
        */
        itemCopy(p) {
            const index = this.schema.properties.findIndex((e) => e === p)
            if (index !== -1) {
                const item = clone({
                    ...p,
                    model: `${p.widget}_${Math.floor(Math.random() * 1000000)}`
                })
                this.selectProperty = item
                this.schema.properties.splice(index + 1, 0, item)
            }
        }
    }
}
</script>

<style lang="scss" scoped>
.drag-form-content{
    display: flex;
    min-width: 1000px;
    overflow-x: auto;
    .left{
        width: 260px;
        max-width: 260px;
        user-select: none;
        border-right: 1px solid #DCDFE6;
        .title{
            padding-top: 4px;
            padding-bottom: 5px;
            padding-left: 20px;
            line-height: 40px;
            border-bottom: 1px solid #DCDFE6;
        }
    }
    .center{
        flex: 1;
        user-select: none;
        box-sizing: border-box;
        background-color: #F7F7F8;
        border-bottom: 1px solid #DCDFE6;
        .center-toolbar{
            background-color: #FFFFFF;
        }
        .center-form{
            padding: 6px;
            position: relative;
        }
        .form-empty{
            font-size: 20px;
            text-align: center;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            user-select: none;
            color: #C0C4CC;
        }
    }
    .right{
        width: 300px;
        max-width: 300px;
        border-left: 1px solid #DCDFE6;
        border-bottom: 1px solid #DCDFE6;
    }

    .widget-draggable{
        height: calc( 100vh - 78px );
        overflow-y: auto;
        padding-left: 10px;
        border-bottom: 1px solid #DCDFE6;
    }
    .widget-col{
        padding-right: 10px;
    }
    .widget{
        border: 1px solid #DCDFE6;
        border-radius: 4px;
        padding: 7px 10px;
        cursor: grab;
        margin-top: 10px;
        text-align: left;
        background-color: #F4F6FC;
        transition: border 0.2s, color 0.2s;
        &:hover{
            color: #409EFF;
            border-color: #409EFF;
        }
    }
    .form-draggable{
        height: calc( 100vh - 90px );
        overflow-y: auto;
        padding-bottom: 80px;
        background-color: #ffffff;

        .widget-chosen{
            width: 100%;
            height: 0px;
            border: 2px solid #F56C6C;
            overflow: hidden;
        }
        .form-chosen{}
    }
}
</style>
